
using ContractDocumentation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;


namespace ContractDocumentation
{
    class GroupVisualizer
    {
        static XNamespace xs = "http://www.w3.org/2001/XMLSchema";

        internal static IEnumerable<FrameworkElement> VisualizeGroup(Context context, XElement groupElement)
        {
            if (groupElement.Name != xs + "sequence" ||
                XmlUtils.GetMinOccurs(groupElement) != 1 || XmlUtils.GetMaxOccurs(groupElement) != 1)
            {
                FrameworkElement parent = VisualizeGroupDeclaration(context, groupElement);
                var children = VisualizeGroupContent(context, groupElement);
                return UIUtils.LayoutChildren(context, parent, children);
            }
            else
            {
                return VisualizeGroupContent(context, groupElement);
            }
        }

        internal static IEnumerable<FrameworkElement> VisualizeGroupContent(Context context, XElement groupElement)
        {
            var children = new List<FrameworkElement>();
            foreach (var element in groupElement.Elements())
            {
                if (element.Name == xs + "element") children.AddRange(ElementVisualizer.VisualizeElement(context, element));
                else if (element.Name == xs + "all") children.AddRange(VisualizeGroup(context, element));
                else if (element.Name == xs + "choice") children.AddRange(VisualizeGroup(context, element));
                else if (element.Name == xs + "sequence") children.AddRange(VisualizeGroup(context, element));
            }
            return children;
        }

        static FrameworkElement VisualizeGroupDeclaration(Context context, XElement groupElement)
        {
            bool isOptional = XmlUtils.GetMinOccurs(groupElement) < 1;
            bool isMulti = XmlUtils.GetMaxOccurs(groupElement) > 1;

            Grid grid = new Grid();
            Ellipse ellipse = UIUtils.CreateGroupEllipse(isOptional);
            if (isMulti)
            {
                Ellipse ellipse2 = UIUtils.CreateGroupEllipse(false);
                ellipse2.Stroke = Brushes.Gray;

                Ellipse ellipse3 = UIUtils.CreateGroupEllipse(false);
                ellipse3.Stroke = Brushes.Gray;

                ellipse.Margin = new Thickness(0, 0, 8, 8);
                ellipse2.Margin = new Thickness(4, 4, 4, 4);
                ellipse3.Margin = new Thickness(8, 8, 0, 0);

                grid.Children.Add(ellipse3);
                grid.Children.Add(ellipse2);
            }
            grid.Children.Add(ellipse);
            TextBlock textBlock = new TextBlock()
            {
                Text = groupElement.Name.LocalName,
                TextAlignment = TextAlignment.Center,
                FontStyle = FontStyles.Italic,
                Padding = new Thickness(6),
                MinWidth = 48,
            };
            grid.Children.Add(textBlock);
            if (isMulti)
            {
                textBlock.Padding = new Thickness(6, 6, 14, 14);
                grid.Tag = new VisualizerTag()
                {
                    GetLeftConnectionPoint = () => new Point(0, (grid.DesiredSize.Height / 2) - 4),
                    GetRightConnectionPoint = () => new Point(grid.DesiredSize.Width - 8, (grid.DesiredSize.Height / 2) - 4),
                };
            }
            return grid;
        }
    }
}
